package cn.tedu.kcircle.gateway.handler;

import cn.tedu.kcircle.common.exception.BusinessException;
import cn.tedu.kcircle.common.restful.JsonResult;
import cn.tedu.kcircle.common.restful.ResponseCode;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.function.Supplier;

@Component
@Order(0)
@Slf4j
 //网关有一个ResponseStatusExceptionHandler 会来处理这个异常 需要在它之前处理才会生效
public class CustomErrorExceptionHandler implements ErrorWebExceptionHandler {
    /**
     * 网关运行过程中 所有过滤器的返回异常 Mono.error(exception)
     * @param exchange
     * @param e
     * @return
     */
    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable e) {
        ServerHttpResponse response = exchange.getResponse();
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        log.error("网关执行出现异常",e);
        String result=e instanceof BusinessException ?JSON.toJSONString(JsonResult.failed((BusinessException) e)):JSON.toJSONString(JsonResult.failed(ResponseCode.INTERNAL_SERVER_ERROR,"服务器内部错误"));
        DataBuffer wrap = response.bufferFactory().wrap(result.getBytes(StandardCharsets.UTF_8));
        Mono<DataBuffer> objectMono = Mono.fromSupplier(new Supplier<DataBuffer>() {

            @Override
            public DataBuffer get() {
                return wrap;
            }
        });
        return response.writeWith(objectMono);
    }
}
